原文地址 zhuanlan.zhihu.com
Minimax 算法即极小极大值算法,是一种回溯算法,用于决策制定和博弈论。尤其是在双人之间的零和博弈中,假定两人都是绝对理性的情况下找出最佳决策方式。他广泛应用于两人回合制游戏,例如井字棋,国际象棋等。
在 Minimax 中,两人被称为最大化者和最小化者。最大化者试图获得尽可能高的分数,而最小化者试图做相反的事情并获得尽可能低的分数。
每个棋盘状态都有一个与之关联的值。在给定的状态下,如果最大化者占上风,那么棋盘的得分将趋向于某个正值。如果最小化者在该棋盘状态下占上风,那么它往往是一些负值。棋盘的价值是通过一些启发式计算的,这些启发式对于每种类型的游戏都是独一无二的。
评价函数
1 | func evaluate(board [][]byte) int { |
对于双人零和博弈游戏来说,我必须首先制定一套根据实际状态计算双方得失的函数,我们称其为评价函数。 拿棋类游戏来举例的话,就是根据当前的棋盘状态 board 制定一套计算双方得失的规则,然后计算分数 score 返回。
minimax 函数
1 | func minimax(board [][]byte,depth int,isMax bool) int { |
max 最大化者代表我方,min 最小化者代表对手。我方要尽可能令评价分数最大化,对方要尽可能令评价分数最小化。
这个函数实质上就是对决策树进行遍历,返回对我方最有利,即评价分数最高的值。
最佳走法函数
1 | // 决策(棋法)结构体 |
利用 minima 函数返回最佳决策(走法)。
数学原理
$$
v_i = \mathop{max}\limits_{a_i} \ \mathop{min}\limits_{a_{-i}} \ v_i(a_i,a_{-i})
$$
$i$ 是当前玩家索引
$-i$ 是对手玩家索引
$a_i$ 代表当前玩家采取的行动
$a_{-i}$ 代表对手玩家采取的行动
$v_i$ 是当前局势状态的评估价值
$v_i$ 越是大的正数代表当前局势对于玩家 $i$ 更有利,$v_i$ 越是小的的负数代表当前局势对于玩家 $-i$ 更有利
minimax 算法伪代码
1 | function minimax(node, depth, maximizingPlayer) is |
图解算法:实际上就是决策树的遍历过程
实例代码 - Go 语言
minimax 算法游戏 AI
1 | package main |
主程序
1 | package main |
控制台
1 | - - - |